package com.movie2.controller;

import com.movie2.config.MyConstants;
import com.movie2.model.entity.*;
import com.movie2.model.vo.EmailVo;
import com.movie2.model.vo.LoginVo;
import com.movie2.service.*;
import com.movie2.util.JwtTokenUtil;
import com.movie2.util.MD5Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.naming.Name;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;

@RestController
@RequestMapping("/api/user")
@CrossOrigin
@Slf4j
public class UserController {
    @Autowired
    UserService userService;

    // 验证用户名是否存在
    @PostMapping("/isExist")
    public Map<String, String> isExist(@RequestBody EmailVo vo) {
        log.info("UserController ----> isExist(EmailVo vo)");
        Map<String, String> map = new HashMap<>();
        User user = new User();
        user.setUsername(vo.getEmail());//只放置登录名
        List<User> users = userService.selectUsersByCondition(user);
        if (users == null || users.size() == 0) {
            // 没有找到，就可以注册
            map.put("msg", "用户名不存在，可以注册");
            map.put("success", "success");
        } else {
            map.put("msg", "用户名存在，不可以注册");
            map.put("success", "fail");
        }
        return map;
    }

    // 注册功能
    @PostMapping("/register")
    public Map<String, Object> register(@RequestBody LoginVo vo) {
        log.info("UserController ----> register(LoginVo vo)");
        Map<String, Object> map = new HashMap<>();
        String token = vo.getToken();
        // 获得token中加密的验证码
        String code = JwtTokenUtil.getUserName(token);
        if (code.equalsIgnoreCase(vo.getEmailCode())) {
            User user = new User();
            user.setUsername(vo.getUsername());
            user.setPassword(vo.getPassword());
            user.setEmail(vo.getEmail());
            user.setAvatar("/images/avatar/default.png");
            user.setNickname("新用户");

            int insert = userService.insert(user);
            if (insert == 1) {
                map.put("msg", "注册成功");
            } else {
                map.put("msg", "注册失败");
            }
        } else {
            map.put("msg", "验证码错误");
        }
        return map;
    }

    // 登录功能
    @PostMapping("/login")
    public Map<String, Object> login(@RequestBody LoginVo vo) {
        log.info("UserController ----> login(LoginVo vo)");
        Map<String, Object> map = new HashMap<>();
        // 获得token中加密的验证码
        User user = new User();
        user.setUsername(vo.getUsername());
        List<User> users = userService.selectUsersByCondition(user);
        if (users == null || users.size() == 0) {
            map.put("msg", "用户名或密码错误");
            map.put("success", "fail");
        } else {
            User result = users.get(0);
            // 用户是否已经禁用
            if (result.getStatus() == 1) {
                map.put("msg", "该用户已被禁用，请联系管理员");
                map.put("success", "fail");
            } else {
                // 加密密码，判断密码是否匹配
                String newPass = MD5Util.md5To32String(vo.getPassword(), result.getSalt(), result.getSaltIndex());
                if (newPass.equalsIgnoreCase(result.getPassword())) {
                    // 登录成功
                    result.setErrorNum(0);
                    result.setStatus(0);
                    map.put("msg", "登录成功");
                    map.put("success", "success");
                    List<String> list = new ArrayList<>();
                    list.add("user");
                    String token = JwtTokenUtil.createToken(result.getUsername(), list, JwtTokenUtil.EXPIRATION_TIME);
                    map.put("token", token);
                    map.put("user", result);
                } else {
                    // 密码加密后与数据库中存储的不一致
                    result.setErrorNum(result.getErrorNum() + 1);
                    map.put("msg", "用户名或密码错误");
                    map.put("success", "fail");
                    if (result.getErrorNum() >= 5) {
                        // 锁定账户
                        result.setStatus(1);
                        map.put("msg", "用户输入密码连续错误已达5次，该账户被禁用，请联系管理员");
                        map.put("success", "fail");
                    }
                }
                userService.updateByPrimaryKey(result);
            }
        }
        return map;
    }

    // 登录功能
    @GetMapping("/id")
    public Map<String, Object> getUserId(@RequestParam("id") int id) {
        log.info("UserController ----> getUserId(@RequestParam(\"id\") int id)");
        Map<String, Object> map = new HashMap<>();
        User user = userService.selectByPrimaryKey(id);
        user.setAvatar(MyConstants.MY_URL + user.getAvatar());
        map.put("user", user);
        return map;
    }


    @Value("${xhn.avatar.upload}")
    String avatarUploadPath;

    // 修改个人设置
    // 单文件上传
    @PostMapping("/avatar/upload")
    public Map<String, String> avatarUpload(@RequestBody MultipartFile file) throws IOException {
        log.info("头像上传：PosterController类，upload()");
        Map<String, String> map = new HashMap<>();

        File path = new File(avatarUploadPath);
        if (!path.exists()) {
            path.mkdirs();//文件夹不存在，创建文件夹
        }
        String originalFilename = file.getOriginalFilename();//获得原始的文件名“7.jpg”
        int index = originalFilename.lastIndexOf(".");
        String newName = originalFilename.substring(0, index) + "_" + UUID.randomUUID().toString() + originalFilename.substring(index);
        // 保存文件
        try {
            file.transferTo(new File(avatarUploadPath + newName));//不出现异常，就是文件上传成功
            // 对数据库进行操作（把图片的路径保存到数据库中），varchar/char （建议使用）
            // blob二进制文件类型，把图片的二进制文件直接保存到数据库中，（很少用）
            map.put("message", "文件保存成功");
            map.put("db", "数据库保存成功");
            map.put("name", "/images/avatar/" + newName);
            // return "不出现异常，就是文件上传成功";
        } catch (IOException ioException) {
            map.put("message", "文件保存失败");
            ioException.printStackTrace();//文件上传失败
            // return "出现异常，文件上传失败";
            throw ioException;
        }
        return map;
    }


    @PostMapping("/update")
    public Map<String, Object> updateSet(@RequestBody User user) {
        log.info("修改个人设置：UserController -> updateSet(@RequestBody User user)");
        Map<String, Object> map = new HashMap<>();
        User result = userService.selectByPrimaryKey(user.getId());
        // 判断是否修改了密码，若是，则加密
        if (!user.getPassword().equalsIgnoreCase(result.getPassword())) {
            String newPass = MD5Util.md5To32String(user.getPassword(), result.getSalt(), result.getSaltIndex());
            user.setPassword(newPass);
        }
        int isA = user.getAvatar().indexOf(MyConstants.MY_URL);
        if (isA != -1) {
            user.setAvatar(user.getAvatar().replace(MyConstants.MY_URL, ""));
        }

        int count = userService.updateByPrimaryKey(user);
        if (count == 1) {
            map.put("success", "ok");
        }
        return map;
    }

    @Autowired
    RegistrationService registrationService;
    @Autowired
    FilmReviewService filmReviewService;
    @Autowired
    MessageService messageService;
    @Autowired
    OrderService orderService;
    @Autowired
    WorkerEvaluateService workerEvaluateService;

    @GetMapping("/delete")
    public Map<String, Object> deleteUser(@RequestParam("uid") Integer uid) {
        Map<String, Object> map = new HashMap<>();
        int count;
        count = userService.deleteByPrimaryKey(uid);
        FilmReview filmReview=new FilmReview();
        filmReview.setUid(uid);
        count = filmReviewService.deleteByCondition(filmReview);
        Message message=new Message();
        message.setUid(uid);
        count = messageService.deleteByCondition(message);
        Order order=new Order();
        order.setUid(uid);
        count= orderService.deleteByCondition(order);
        WorkerEvaluate workerEvaluate=new WorkerEvaluate();
        workerEvaluate.setUid(uid);
        count=workerEvaluateService.deleteByCondition(workerEvaluate);


        if (count == 1) {
            map.put("success", "ok");
        } else {
            map.put("success", "fail");
        }
        return map;
    }

}
